vue项目中常见的三种文件类型在线预览实现(pdf/word/excel表格)

您所在的位置:网站首页 vue3 pdf预览 vue项目中常见的三种文件类型在线预览实现(pdf/word/excel表格)

vue项目中常见的三种文件类型在线预览实现(pdf/word/excel表格)

2022-07-09 19:02| 来源: 网络整理| 查看: 265

vue项目中常见的三种文件类型在线预览实现(pdf/word/excel表格)

目录前言一、预览word文件1.安装 npm 依赖2.预览在线地址文件3.预览本地文件二、预览excel表格1.安装依赖2.预览在线表格三、pdf预览1.安装依赖vue-pdf2.在需要的页面注册3.使用4.加载本地pdf文件5.解决pdf使用自定义字体预览和打印乱码问题:pdfjsWrapper.js总结

前言

之前做PDF预览一直用的pdf.js,这次没有太多附加需求比较简单简,所以决定用vue-pdf这个组件,虽然说它没有原生那样强大,但已经满足常用的需求了,重要是这个组件使用简单。顺便也把word文件和excel表格预览也整理了下,接下来我们直接进入正题!

一、预览word文件

1.安装 npm 依赖 npm i [email protected] npm i jszip

2.预览在线地址文件 import axios from "axios" const docx = require("docx-preview"); window.JSZip = require("jszip") export default { mounted(){ axios({ method: "get", responseType: "blob", // 设置响应文件格式 url: "/docx", }).then(({data}) => { docx.renderAsync(data,this.$refs.file) // 渲染到页面预览 }) } }

3.预览本地文件 const docx = require("docx-preview"); window.JSZip = require("jszip") export default { methods:{ preview(e){ docx.renderAsync(this.$refs.file.files[0],this.$refs.preview) // 渲染到页面预览 } } }; .my-component{ width: 100%; height: 90vh; border: 1px solid #000; }

二、预览excel表格

1.安装依赖 npm i xlsx

2.预览在线表格 import axios from "axios" import XLSX from "xlsx"; export default { data(){ return { tableau: null, } }, mounted(){ axios.get("/xlsx",{ responseType: "arraybuffer", // 设置响应体类型为arraybuffer }).then(({data})=> { let workbook = XLSX.read(new Uint8Array(data), {type:"array"}); // 解析数据 var worksheet = workbook.Sheets[workbook.SheetNames[0]]; // workbook.SheetNames 下存的是该文件每个工作表名字,这里取出第一个工作表 this.tableau = XLSX.utils.sheet_to_html(worksheet); // 渲染 }) } }

三、pdf预览

1.安装依赖vue-pdf npm install --save vue-pdf

2.在需要的页面注册 import PDF from "vue-pdf" export default { components:{ PDF, }, data(){ return { } }

3.使用

一般预览pdf时都是很多页的,为了提升性能可以做个分页。page: 当前显示的页数,比如第一页page=1;rotate : 旋转角度,比如0就是不旋转,+90,-90 就是水平旋转。progress :当前页面的加载进度,范围是0-1 ,等于1的时候代表当前页已经完全加载完成了。page-loaded :页面加载成功的回调函数,不咋能用到。num-pages :总页数;error :加载错误的回调link-clicked:单机pdf内的链接会触发。print 这个是打印函数。(注意:谷歌浏览器预览时会出现乱码,这个问题是因为你pdf中使用了自定义字体导致的。若要解决须替换node_modules/vue-pdf/src/pdfjsWrapper.js,替换的pdfjsWrapper.js我放在文章最后)

上一页 下一页 {{pageNum}}/{{pageTotalNum}} 顺时针旋转 逆时针旋转 打印 import PDF from "vue-pdf" export default { components:{ PDF, }, data(){ return { previewDialog:false, url: "http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf", pageNum: 1, pageTotalNum: 1, pageRotate: 0, // 加载进度 loadedRatio: 0, curPageNum: 0, }, methods:{ /** * 预览PDF */ previewPDF(row,index) { this.previewDialog = true; console.log("", row,index); }, // 上一页函数, prePage() { var page = this.pageNum page = page > 1 ? page - 1 : this.pageTotalNum this.pageNum = page }, // 下一页函数 nextPage() { var page = this.pageNum page = page < this.pageTotalNum ? page + 1 : 1 this.pageNum = page }, // 页面顺时针翻转90度。 clock() { this.pageRotate += 90 }, // 页面逆时针翻转90度。 counterClock() { this.pageRotate -= 90 }, // 页面加载回调函数,其中e为当前页数 pageLoaded(e) { this.curPageNum = e }, // 错误时回调函数。 pdfError(error) { console.error(error) }, // 打印全部 pdfPrintAll() { /** * 打印界面字符乱码是因为你pdf中使用了自定义字体导致的,谷歌浏览器打印的时候预览界面真的变成了真·方块字 ,解决方案如下: * 用文章最后的pdfjsWrapper.js在替换掉node_modules/vue-pdf/src/pdfjsWrapper.js */ console.log("打印"); this.$refs.pdf.print() }, }, }

4.加载本地pdf文件

如果需要加载本地pdf文件(不需要则不用配置),需要我们做一下本地配置flie-loader才行,否则webpack无法编译pdf类型的文件,配置方法也很简单,在项目根目录找到vue.config.js文件(若没有则在根目录下新建一个vue.config.js)。之后再url:require("…/assets/xxx.pdf")就没有任何问题了,注意,vue-pdf src接收的是string对象,如果直接传url这里报错了,需要传url.default一下。

先安装file-loader

npm install --save file-loader

然后在vue.config.js中加入以下内容:

module.exports = { chainWebpack: config => { const fileRule = config.module.rule("file") fileRule.uses.clear() fileRule .test(/.pdf|ico$/) .use("file-loader") .loader("file-loader") .options({ limit: 10000, }) }, publicPath: "./" }

5.解决pdf使用自定义字体预览和打印乱码问题:pdfjsWrapper.js import { PDFLinkService } from "pdfjs-dist/es5/web/pdf_viewer"; var pendingOperation = Promise.resolve(); export default function(PDFJS) { function isPDFDocumentLoadingTask(obj) { return typeof(obj) === "object" && obj !== null && obj.__PDFDocumentLoadingTask === true; // or: return obj.constructor.name === "PDFDocumentLoadingTask"; } function createLoadingTask(src, options) { var source; if ( typeof(src) === "string" ) source = { url: src }; else if ( src instanceof Uint8Array ) source = { data: src }; else if ( typeof(src) === "object" && src !== null ) source = Object.assign({}, src); else throw new TypeError("invalid src type"); // source.verbosity = PDFJS.VerbosityLevel.INFOS; // source.pdfBug = true; // source.stopAtErrors = true; if ( options && options.withCredentials ) source.withCredentials = options.withCredentials; var loadingTask = PDFJS.getDocument(source); loadingTask.__PDFDocumentLoadingTask = true; // since PDFDocumentLoadingTask is not public if ( options && options.onPassword ) loadingTask.onPassword = options.onPassword; if ( options && options.onProgress ) loadingTask.onProgress = options.onProgress; return loadingTask; } function PDFJSWrapper(canvasElt, annotationLayerElt, emitEvent) { var pdfDoc = null; var pdfPage = null; var pdfRender = null; var canceling = false; canvasElt.getContext("2d").save(); function clearCanvas() { canvasElt.getContext("2d").clearRect(0, 0, canvasElt.width, canvasElt.height); } function clearAnnotations() { while ( annotationLayerElt.firstChild ) annotationLayerElt.removeChild(annotationLayerElt.firstChild); } this.destroy = function() { if ( pdfDoc === null ) return; // Aborts all network requests and destroys worker. pendingOperation = pdfDoc.destroy(); pdfDoc = null; } this.getResolutionScale = function() { return canvasElt.offsetWidth / canvasElt.width; } this.printPage = function(dpi, pageNumberOnly) { if ( pdfPage === null ) return; // 1in == 72pt // 1in == 96px var PRINT_RESOLUTION = dpi === undefined ? 150 : dpi; var PRINT_UNITS = PRINT_RESOLUTION / 72.0; var CSS_UNITS = 96.0 / 72.0; var printContainerElement = document.createElement("div"); printContainerElement.setAttribute("id", "print-container") function removePrintContainer() { printContainerElement.parentNode.removeChild(printContainerElement); } new Promise(function(resolve, reject) { printContainerElement.frameBorder = "0"; printContainerElement.scrolling = "no"; printContainerElement.width = "0px;" printContainerElement.height = "0px;" printContainerElement.style.cssText = "position: absolute; top: 0; left: 0"; window.document.body.appendChild(printContainerElement); resolve(window) }) .then(function(win) { win.document.title = ""; return pdfDoc.getPage(1) .then(function(page) { var viewport = page.getViewport({ scale: 1 }); printContainerElement.appendChild(win.document.createElement("style")).textContent = "@supports ((size:A4) and (size:1pt 1pt)) {" + "@page { margin: 1pt; size: " + ((viewport.width * PRINT_UNITS) / CSS_UNITS) + "pt " + ((viewport.height * PRINT_UNITS) / CSS_UNITS) + "pt; }" + "}" + "#print-canvas { display: none }" + "@media print {" + "body { margin: 0 }" + "#print-canvas { page-break-before: avoid; page-break-after: always; page-break-inside: avoid; display: block }" + "body > *:not(#print-container) { display: none; }" + "}"+ "@media screen {" + "body { margin: 0 }" + "}" return win; }) }) .then(function(win) { var allPages = []; for ( var pageNumber = 1; pageNumber


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3